package com.example.aspect;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Aspect
@Component
public class LogAspect {
    public static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
    public final ObjectMapper objectMapper = new ObjectMapper();
    // com.example.demo.controller下所有的类的方法
    @Pointcut("execution(* com.example.demo.controller.*.*(*))")
    public void controllerPointCut(){
    }

    @Before("controllerPointCut()")
    public void before(JoinPoint joinPoint){
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        if (requestAttributes!=null){
            HttpServletRequest request = requestAttributes.getRequest();

            Map<String, Object> logMap = new HashMap<>();
            logMap.put("URL",request.getRequestURL().toString());
            logMap.put("HTTP_METHOD",request.getMethod());
            logMap.put("ip",request.getRemoteHost());
            logMap.put("CLASS_METHOD",joinPoint.getSignature().getDeclaringTypeName()+"."+joinPoint.getSignature().getName());
            logMap.put("ARGS", Arrays.toString(joinPoint.getArgs()));

            try {
                logger.info("REQUEST {} "+objectMapper.writeValueAsString(logMap));
            }catch (Exception e){
                logger.error("",e);
            }
        }
    }

    @AfterReturning(pointcut ="controllerPointCut()",returning = "result")
    public void afterReturning(JoinPoint joinPoint,Object result){
        try {
            logger.info("REQUEST {} "+objectMapper.writeValueAsString(result));
        }catch (Exception e){
            logger.error("",e);
        }
    }
    @AfterThrowing(pointcut = "controllerPointCut()",throwing = "e")
    public void afterThrowing(JoinPoint joinPoint,Throwable e){
        Map<String, Object> logMap = new HashMap<>();
        logMap.put("METHOD",joinPoint.getSignature().getDeclaringTypeName()+"."+joinPoint.getSignature().getName());
        logMap.put("Exception",e.getMessage());
        try {
            logger.info("REQUEST {} "+objectMapper.writeValueAsString(logMap));
        }catch (Exception ex){
            logger.error("",ex);
        }
    }

}
